﻿var estadoInicial = new Kiwi.State('EstadoInicial');

estadoInicial.preload = function () {
    this.addImage('cannonBall', 'cannonBall.png');
};

estadoInicial.create = function () {
    Kiwi.State.prototype.create.call(this);

    this.background = new Kiwi.GameObjects.StaticImage(this, this.textures['Fondo'], 0, 0);
    this.mainTank = new MainTank(MainTankType, this);
    this.cannonBallGroup = new Kiwi.Group(this);

    this.acelerarKey = this.game.input.keyboard.addKey(Kiwi.Input.Keycodes.W);
    this.girarIzquierdaKey = this.game.input.keyboard.addKey(Kiwi.Input.Keycodes.A);
    this.girarDerechaKey = this.game.input.keyboard.addKey(Kiwi.Input.Keycodes.D);
    this.desacelerarKey = this.game.input.keyboard.addKey(Kiwi.Input.Keycodes.S);
    this.fireKey = this.game.input.keyboard.addKey(Kiwi.Input.Keycodes.SPACEBAR);
    this.girarIzquierdaCabezaKey = this.game.input.keyboard.addKey(Kiwi.Input.Keycodes.Q);
    this.girarDerechaCabezaKey = this.game.input.keyboard.addKey(Kiwi.Input.Keycodes.E);

    this.addChild(this.background);
    this.addChild(this.mainTank.tank.graphicHandler);
    this.addChild(this.mainTank.tank.tankCannon.graphicHandler);
    this.addChild(this.cannonBallGroup);
};

estadoInicial.update = function () {
    Kiwi.State.prototype.update.call(this);

    if (this.girarDerechaKey.isDown) {
        this.mainTank.move(Right);
    }
    if (this.girarIzquierdaKey.isDown) {
        this.mainTank.move(Left);
    }
    if (this.girarIzquierdaCabezaKey.isDown) {
        this.mainTank.rotateCannonHeader(Left);
    }
    if (this.girarDerechaCabezaKey.isDown) {
        this.mainTank.rotateCannonHeader(Right);
    }

    if (this.desacelerarKey.isDown) {
        this.mainTank.move(Down);
    }
    if (this.acelerarKey.isDown) {
        this.mainTank.move(Up);
    }

    if (this.game.input.mouse.isDown) {
        var mousePoint = new Kiwi.Geom.Point(this.game.input.mouse.x, this.game.input.mouse.y);
        this.mainTank.pointCannonHeader(mousePoint.x, mousePoint.y);
    }

    if (this.fireKey.isDown) {
        this.openFire();
    }

    document.getElementById("cabezaX").value = this.mainTank.tank.tankCannon.properties.x;
    document.getElementById("cabezaY").value = this.mainTank.tank.tankCannon.properties.y;
    document.getElementById("cabezaPendiente").value = this.mainTank.tank.tankCannon.properties.rotation;
    document.getElementById("arcoTangente").value = this.mainTank.tank.tankCannon.automaticRotationCalculous();
    document.getElementById("caminoDerecho").value = this.mainTank.tank.tankCannon.properties.rightWay;
    document.getElementById("caminoIzquierdo").value = this.mainTank.tank.tankCannon.properties.leftWay;
    document.getElementById("mouseX").value = this.game.input.mouse.x;
    document.getElementById("mouseY").value = this.game.input.mouse.y;
    this.mainTank.update();
};

estadoInicial.openFire = function () {
    this.mainTank.tank.tankCannon.graphicHandler.animation.play("startFire");
    this.mainTank.tank.tankCannon.graphicHandler.animation.getAnimation("startFire").onComplete.add(function () { estadoInicial.createBullet(); });
};

estadoInicial.createBullet = function () {
    var shootingPoint = new Kiwi.Geom.Point(this.mainTank.tank.tankCannon.graphicHandler.x + 100, this.mainTank.tank.tankCannon.graphicHandler.y + 50);
    this.cannonBallGroup.addChild(new CannonBall(this, shootingPoint.x, shootingPoint.y, this.mainTank.tank.tankCannon.graphicHandler.rotation));
    //this.mainTank.tank.tankCannon.graphicHandler.animation.play("reloadFire");
}

var CannonBall = function (state, x, y, rotation) {
    Kiwi.GameObjects.Sprite.call(this, state, state.textures['cannonBall'], x, y, false);

    this.rotation = rotation;
    this.speed = 12;
    CannonBall.prototype.update = function () {
        Kiwi.GameObjects.Sprite.prototype.update.call(this);
        this.x += Math.cos(this.rotation) * this.speed;
        this.y += Math.sin(this.rotation) * this.speed;

        if (this.x > elJuego.stage.width || this.x < 0 || this.y > elJuego.stage.height || this.y < 0) {
            this.destroy();
            state.mainTank.tank.tankCannon.graphicHandler.animation.play("reloadFire");
        }
    }
};
Kiwi.extend(CannonBall, Kiwi.GameObjects.Sprite);

function MainTank(type, global) {
    this.tank = new RegularTank(type, global);
    this.move = function (direction) {
        this.tank.move(direction);
    }
    this.rotateCannonHeader = function (direction) {
        this.tank.rotateCannonHeader(direction);
    }
    this.pointCannonHeader = function (x, y) {
        this.tank.pointCannonHeader(x, y);
    }
    this.update = function () {
        this.tank.update();
    }
}

function RegularTank(type, global) {

    this.type = type;
    this.graphicHandler = new Kiwi.GameObjects.Sprite(global, global.textures.TanqueSprite, 100, 100);
    this.graphicHandler.transform.rotPointX = 64;
    this.graphicHandler.transform.rotPointY = 48;
    this.graphicHandler.rotation = 0;
    this.state = IdleState;
    this.isLocked = false;
    this.properties = new TankExtendedProperties(TankExtendedPropertiesType);
    this.tankCannon = new TankCannon("TankCannon", global);
    this.move = function (direction) {
        switch (direction) {
            case Right:
            case Left:
                this.rotate(direction);
                break;
            case Up:
            case Down:
                this.accelarate(direction);
                break;
        }
    }

    this.accelarate = function (direction) {
        this.state = MovingState;
        if (direction == Down && this.properties.isGoingForward || direction == Up && !this.properties.isGoingForward) {
            this.properties.speed -= this.properties.acceleration;
        }
        else {
            this.properties.speed += this.properties.acceleration;
        }
        if (this.properties.speed < 0) {
            this.properties.isGoingForward = !this.properties.isGoingForward;
            this.properties.speed = -this.properties.speed;
        }

        if (this.properties.speed > this.properties.maxSpeed)
            this.properties.speed = this.properties.maxSpeed;
    }

    this.rotate = function (direction) {
        if (this.properties.speed > 0) {
            if (direction == Right) {
                this.properties.rotation += Kiwi.Utils.GameMath.degreesToRadians(this.properties.rotationSpeed());
            }
            else {
                this.properties.rotation -= Kiwi.Utils.GameMath.degreesToRadians(this.properties.rotationSpeed());
            }
            this.tankCannon.move(direction, this.properties.rotationSpeed());
        }
        var degrees = Kiwi.Utils.GameMath.radiansToDegrees(this.properties.rotation);
        if (Math.abs(degrees) >= 359)
            this.properties.rotation = 0;
    };

    this.rotateCannonHeader = function (direction) {
        this.tankCannon.move(direction, null);
    }

    this.pointCannonHeader = function (x, y) {
        this.tankCannon.pointCannonHeader(x, y);
    }

    this.updatePosition = function () {
        if (!(this.state == MovingState)) {
            this.properties.slowDown();            
        }

        if (this.properties.isGoingForward) {
            this.properties.x += this.properties.speed * Math.cos(this.properties.rotation);
            this.properties.y += this.properties.speed * Math.sin(this.properties.rotation);
        }
        else {
            this.properties.x -= this.properties.speed * Math.cos(this.properties.rotation);
            this.properties.y -= this.properties.speed * Math.sin(this.properties.rotation);
        }

        this.tankCannon.properties.x = this.properties.x;
        this.tankCannon.properties.y = this.properties.y;
    }

    this.update = function () {
        this.updatePosition();
        this.graphicHandler.rotation = this.properties.rotation;
        this.graphicHandler.x = this.properties.x;
        this.graphicHandler.y = this.properties.y;
        this.tankCannon.update();
        this.state = IdleState;
    }
}

function TankCannon(type, global) {
    this.type = type;
    this.graphicHandler = new Kiwi.GameObjects.Sprite(global, global.textures.CabezaTanqueSprite, 100, 100);
    //this.graphicHandler.animation.add('disparando', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], 0.1, false);
    this.graphicHandler.animation.add("startFire", [0, 1, 2], 0.1, false);
    this.graphicHandler.animation.add("reloadFire", [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], 0.1, false);
    this.graphicHandler.transform.rotPointX = 64;
    this.graphicHandler.transform.rotPointY = 48;
    this.rotation = 0;
    this.state = IdleState;

    this.properties = new TankCannonExtendedProperties(TankCannonExtendedPropertiesType);
    this.move = function (direction, rotationSpeed) {
        if (direction == Right || direction == Left)
            this.rotate(direction, rotationSpeed);
    }

    this.rotate = function (direction, rotationSpeed) {
        if (rotationSpeed == null)
            rotationSpeed = this.properties.rotationSpeed;
        if (direction == Right)
            this.properties.rotation += Kiwi.Utils.GameMath.degreesToRadians(rotationSpeed);
        else
            this.properties.rotation -= Kiwi.Utils.GameMath.degreesToRadians(rotationSpeed);
        var degrees = Kiwi.Utils.GameMath.radiansToDegrees(this.properties.rotation);
        if (Math.abs(degrees) >= 359)
            this.properties.rotation = 0;
    }

    this.pointCannonHeader = function (x, y) {
        //necesitamos ajustar al centro del grafico!
        this.properties.objectiveX = x;
        this.properties.objectiveY = y;
    }

    this.automaticRotationCalculous = function () {
        if (this.properties.objectiveX == null)
            return 0;
        var objective = new Kiwi.Geom.Point(this.properties.objectiveX, this.properties.objectiveY);
        //se necesita ajustar al centro del grafico!
        var actual = new Kiwi.Geom.Point(this.properties.x + this.graphicHandler.transform.rotPointX, this.properties.y + this.graphicHandler.transform.rotPointY);
        var finalRotation = actual.angleTo(objective);
        return finalRotation;
    }

    this.automaticPointCannonHeader = function () {
        var finalRotation = this.automaticRotationCalculous();
        var gotoRight = false;

        //tenemos q buscar el camino mas corto!!
        this.properties.rightWay = CalculateDistance(this.properties.rotation, finalRotation, Right);
        this.properties.leftWay = CalculateDistance(this.properties.rotation, finalRotation, Left);        
        if (this.properties.rightWay < this.properties.leftWay) {
            gotoRight = true;
        }

        if (gotoRight)
            this.rotate(Right, null);
        else
            this.rotate(Left, null)

        if (gotoRight && this.properties.rightWay <= Kiwi.Utils.GameMath.degreesToRadians(this.properties.rotationSpeed)) {
            this.properties.objectiveX = null;
        }
        else if (!gotoRight && this.properties.leftWay <= Kiwi.Utils.GameMath.degreesToRadians(this.properties.rotationSpeed))
            this.properties.objectiveX = null;
    }

    this.update = function () {

        this.graphicHandler.rotation = this.properties.rotation;
        this.graphicHandler.x = this.properties.x;
        this.graphicHandler.y = this.properties.y;
        if (this.properties.objectiveX != null) {
            this.automaticPointCannonHeader();
        }
    }
}

function TankExtendedProperties(type) {
    this.type = type;
    this.acceleration = 0.5;
    this.desacceleration = 0.3;
    this.isGoingForward = true;    
    this.maxSpeed = 4;
    this.rotation = 0;
    this.speed = 0;
    this.x = 0;
    this.y = 0;

    this.canShoot = function () { return this.speed == 0; };
    this.rotationSpeed = function () { return this.speed / 2; }
    this.slowDown = function () {
        this.speed -= this.desacceleration;
        if (this.speed < 0)
            this.speed = 0;
    }

}

function TankCannonExtendedProperties(type) {
    this.type = type;
    this.rotation = 0;
    this.objectiveX = null;
    this.objectiveY = null;
    this.rotationSpeed = 0.2;
    this.x = 0;
    this.y = 0;
    this.rightWay = 0;
    this.leftWay = 0;
}

//Helpers
function CalculateDistance(currentGradian, objectiveRadian, direction) {
    var currentPositiveGradian = 0;
    var objectivePositiveRadian = 0;
    if (direction == Right) {
        currentPositiveGradian = CalculateRightWayDistanceFromZero(currentGradian);
        objectivePositiveRadian = CalculateRightWayDistanceFromZero(objectiveRadian);
    }
    else {
        currentPositiveGradian = CalculateLeftWayDistanceFromZero(currentGradian);
        objectivePositiveRadian = CalculateLeftWayDistanceFromZero(objectiveRadian);

    }

    if (currentPositiveGradian < objectivePositiveRadian)
        return objectivePositiveRadian - currentPositiveGradian;
    else
        return (MaxRadians * 2) - currentPositiveGradian + objectivePositiveRadian;
}

function CalculateLeftWayDistanceFromZero(gradian) {
    var absoluteGradian = 0;
    if (gradian < 0)
        absoluteGradian = -gradian;
    else
        absoluteGradian = MaxRadians + (MaxRadians - gradian);
    return absoluteGradian;
}

function CalculateRightWayDistanceFromZero(gradian) {
    var absoluteGradian = 0;
    if (gradian > 0)
        absoluteGradian = gradian;
    else    //los gradianes son negativos asi q van a restar!
        absoluteGradian = MaxRadians + (MaxRadians + gradian);
    return absoluteGradian;
}

//constants
var TankExtendedPropertiesType = "TankExtendedProperties";
var TankCannonExtendedPropertiesType = "TankCannonExtendedProperties";
var TankCannonType = "TankCannon";
var MainTankType = "MainTank";
var Right = "Rigth";
var Left = "Left";
var Up = "Up";
var Down = "Down";
var MaxRadians = 3.1415926536;
var IdleState = "Idle";
var MovingState = "Moving";
var ShootingState = "Shooting";